package main

import "fmt"

func main() {
	r := add(1, 2)
	fmt.Println(r)
	//统计字符串中各个字符出现的个数
	str := "hello world"
	count := make(map[rune]int)

	for _, r := range str {
		count[r]++
	}

	for k, v := range count {
		fmt.Printf("%c: %d\n", k, v)
	}
	//defer
	deferdemo()
	//函数类型
	a := ff1
	fmt.Printf("%T\n", a)
	b := ff2
	fmt.Printf("%T\n", b)
	//调用匿名函数
	ff6(1, 2)
	//调用一次的函数，立即执行函数
	func(x, y int) {
		fmt.Println(x + y)
	}(1, 2)
}

//函数的定义
func add(x int, y int) (ret int) { // 返回值可以被命名，方便在函数体中使用
	return x + y
}

// 没有返回值
func f1(x int, y int) {
	fmt.Println(x + y)
}

//没有参数 没有返回值
func f2() {
	fmt.Println("Hello, World!")
}

//没有参数 有返回值
func f3() int {
	return 3
}

//参数可以命名也可以不命名
//命名返回值就相当于提前声明了一个变量
func f4(x int, y int) (ret int) {
	ret = x + y
	return //使用命名返回值，return后可以省略
}

//多个返回值
func f5(x int, y int) (sum int, difference int) {
	sum = x + y
	difference = x - y
	return
}

//参数类型简写：参数中连续多个参数类型一致，可以将非最后一个参数类型省略
func f6(x, y int) int { // 只有x和y的参数类型一致，可以省略x的参数类型
	return x + y
}

//可变长参数
func f7(x ...int) { // 参数类型为 []int
	fmt.Printf("%T\n", x)
}

//defer 逆序执行
func deferdemo() {
	fmt.Println("start")
	defer fmt.Println("defer1")
	defer fmt.Println("defer2")
	fmt.Println("end")
}

//函数类型作为返回值

func ff1() {
	fmt.Println("f1")
}

func ff2() int {
	return 10
}

//函数类型作为参数
func ff3(x func() int) int {
	return x()
}

func ff5(a, b int) int {
	return a + b
}

//函数类型作为返回值
func ff4(x func() int) func(int, int) int {
	return ff5
}

//匿名函数

var ff6 = func(x int, y int) int {
	fmt.Println(x + y)
	return x + y
}
